In [1]:
import sys
sys.path.append(r'AutomaticDifferentiation\build\Release')
import automatic_differentiation as ad
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from IPython.display import HTML
In [2]:
def display_function_and_derivative(func, x_start, x_end):
    # Create the figure and axis
    fig, ax = plt.subplots(figsize=(10, 6))
    plt.close()  # Prevents displaying the static figure

    # Set the x range for our function
    x_range = np.linspace(x_start, x_end, 100)

    # Calculate function values for the full curve
    y_values = np.array([func(x).get_x() for x in x_range])

    # Plot the main function curve
    ax.plot(x_range, y_values, 'b-', lw=2, label='f(x)')

    # Point that will move along the curve
    point, = ax.plot([], [], 'ro', ms=5)

    # Tangent line that will update
    tangent_line, = ax.plot([], [], 'r-', lw=1, label='Tangent')

    # Text to display the derivative value
    derivative_text = ax.text(0.02, 0.95, '', transform=ax.transAxes)

    # Set up the axes
    ax.set_xlim(x_start, x_end)
    ylim_margin = (max(y_values) - min(y_values)) / 20
    ax.set_ylim(min(y_values) - ylim_margin, max(y_values) + ylim_margin)
    ax.set_xlabel('x', fontsize=14)
    ax.set_ylabel('f(x)', fontsize=14)
    ax.set_title('Function and its Derivative', fontsize=16)
    ax.grid(True)
    ax.legend(loc='lower right')

    # Number of frames in the animation
    frames = 100
    # Points along the curve to evaluate
    animation_x_values = np.linspace(x_start, x_end, frames)

    # Update function for the animation
    def update(frame):
        # Current x value
        x = animation_x_values[frame]
        
        # Get function value and derivative
        dual_number = func(x)
        f_x = dual_number.get_x()
        df_x = dual_number.get_dx()
        
        # Update the point position
        point.set_data([x], [f_x])
        
        # Create tangent line
        # The tangent line is represented by: y = f'(x)*(x-x0) + f(x0)
        tangent_x = np.array([x_start, x_end])
        tangent_y = df_x * (tangent_x - x) + f_x
        tangent_line.set_data(tangent_x, tangent_y)
        
        # Update derivative text
        derivative_text.set_text(f"f'(x) = {df_x:.3f}")
        
        return point, tangent_line, derivative_text

    # Create the animation
    animation = FuncAnimation(fig, update, frames=frames, interval=50, blit=True)

    return animation
    
In [3]:
def polynomial(x):
    dn = ad.DualNumber(x, 1)
    return dn ** 3 + 50 * dn ** 2 - 3 * dn + 18

HTML(display_function_and_derivative(polynomial, -80, 60).to_jshtml())
Out[3]:
No description has been provided for this image
In [4]:
def polynomial(x):
    dn = ad.DualNumber(x, 1)
    return dn ** 2 - 5 * dn + 6 - 5 * dn ** 3 - 5 * np.e ** (-50 * dn ** 2)

HTML(display_function_and_derivative(polynomial, -0.5, 0.5).to_jshtml())
Out[4]:
No description has been provided for this image
In [5]:
def polynomial(x):
    dn = ad.DualNumber(x, 1)
    return np.e ** (-0.1 * dn) * (dn * 5).sin()

HTML(display_function_and_derivative(polynomial, 0, 4).to_jshtml())
Out[5]:
No description has been provided for this image
In [6]:
def polynomial(x):
    dn = ad.DualNumber(x, 1)
    return (dn.sin()).tan() - (3 * dn).cos()

HTML(display_function_and_derivative(polynomial, -3, 5).to_jshtml())
Out[6]:
No description has been provided for this image